﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;

namespace SpectrEngine.Framework.Collision
{
    public sealed class BoundingRect
    {
        #region Properties

        public Vector2 TopLeft;

        public Vector2 BottomRight;

        public float Left
        {
            get { return TopLeft.X; }
            set { TopLeft.X = value; }
        }

        public float Top
        {
            get { return TopLeft.Y; }
            set { TopLeft.Y = value; }
        }

        public float Right
        {
            get { return BottomRight.X; }
            set { BottomRight.X = value; }
        }

        public float Bottom
        {
            get { return BottomRight.Y; }
            set { BottomRight.Y = value; }
        }

        public Vector2 Center
        {
            get { return Vector2.Divide(Vector2.Add(TopLeft, BottomRight), 2.0f); }
        }

        #endregion

        #region Constructors

        public BoundingRect(Vector2 topLeft, Vector2 bottomRight)
        {
            this.TopLeft = topLeft;
            this.BottomRight = bottomRight;
        }

        public BoundingRect(float left, float top, float right, float bottom)
        {
            this.TopLeft = new Vector2(left, top);
            this.BottomRight = new Vector2(right, bottom);
        }

        public BoundingRect(float halfWidth, float halfHeight)
        {
            this.TopLeft = new Vector2(-halfWidth, -halfHeight);
            this.BottomRight = new Vector2(halfWidth, halfHeight);
        }

        #endregion

        public BoundingRect Transform(Matrix value)
        {
            Vector2 topRight = new Vector2(Top, Right);
            Vector2 bottomLeft = new Vector2(Bottom, Left);

            Vector2 tl = Vector2.Transform(TopLeft, value);
            Vector2 tr = Vector2.Transform(topRight, value);
            Vector2 br = Vector2.Transform(BottomRight, value);
            Vector2 bl = Vector2.Transform(bottomLeft, value);

            float top = Math.Min(Math.Min(tl.Y, tr.Y), Math.Min(bl.Y, br.Y));
            float bottom = Math.Max(Math.Max(tl.Y, tr.Y), Math.Max(bl.Y, br.Y));
            float left = Math.Min(Math.Min(tl.X, tr.X), Math.Min(bl.X, br.X));
            float right = Math.Max(Math.Max(tl.X, tr.X), Math.Max(bl.X, br.X));

            return new BoundingRect(left, top, right, bottom);

        }

        #region Collision Methods

        public bool Contains(Vector2 point)
        {
            return point.X >= TopLeft.X && point.X <= BottomRight.X && point.Y >= BottomRight.Y && point.Y <= TopLeft.Y;
        }

        public bool Contains(BoundingRect bbox)
        {
            return (bbox.Left >= Left && bbox.Right <= Right && bbox.Top >= Top && bbox.Bottom <= Bottom);
        }

        public bool Intersects(BoundingRect bbox)
        {
            return !(Left > bbox.Right || Right < bbox.Left || Top > bbox.Bottom || Bottom < bbox.Top);
        }

        #endregion
    }
}
